<template>
    <a-space direction="vertical">
      <a-card title="要素类型配置">
        <a-form ref="searchRef" name="searchBar" :model="searchFormState" :labelCol="{ span: 5, offset: 1 }" @finish="handleSearch">
          <a-row :gutter="24">
            <a-col :span="8">
              <a-form-item name="elementTypeEnName" label="要素类型英文名称">
                <a-input v-model:value="searchFormState.elementTypeEnName"  placeholder="" ></a-input>
              </a-form-item>
            </a-col>
            <a-col :span="8">
              <a-form-item name="elementTypeCnName" label="要素类型中文名称">
                <a-input v-model:value="searchFormState.elementTypeCnName" placeholder="" ></a-input>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row>
            <a-col :span="24" style="text-align: right">
              <a-button type="primary" html-type="submit" :loading="searchLoading" >搜索</a-button>
              <a-button style="margin: 0 8px" @click="() => searchRef?.resetFields()" >重置</a-button>
            </a-col>
          </a-row>
        </a-form>
      </a-card>
      <a-card>
        <a-space>
          <a-button @click="showModal" type="primary"><template #icon> <appstore-add-outlined /> </template>新增</a-button>
          <a-button @click="showEditModal" style="background-color: #f6ffed; color: #237804; border-color: #b7eb8f"><template #icon> <form-outlined /> </template>修改</a-button>
          <a-button @click="showDelete" type="primary" danger><template #icon> <delete-outlined /> </template>删除</a-button>
        </a-space>
      </a-card>
      <a-card title="查询结果">
        <a-table class="ant-table-striped"
          :rowClassName="
            (_record: any, index: number) => (index % 2 === 1 ? 'table-striped' : null)
          "
          :columns="columns"
          :data-source="data"
          rowKey="id"
          :loading="searchLoading"
          :rowSelection="rowSelection"
          @change="
            (pagination: any) => {
              handleSearch(pagination);
            }
          "
          :pagination="{
            position: [`bottomRight`],
            showSizeChanger: true,
            showQuickJumper: true,
            current: pageNum,
            pageSize,
            total: total,
            showTotal: (total: any) => `总计 ${total} 条记录`,
          }">
        </a-table>
      </a-card>
      <a-modal
        ref="modalRef"
        v-model:visible="visible"
        @ok="handleOk"
        style="width: 1200px; top: 0"
      >
        <template #title>
          <div ref="modalTitleRef" style="width: 100%; cursor: move">
            {{ currentAction }}要素类型
          </div>
        </template>
        <a-form ref="formRef" :model="formState" :labelCol="{ span: 5, offset: 1 }" name="form_in_modal">
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="elementTypeEnName" 
                label="要素类型英文名称"
                :rules="[{ required: true, message: '请输入要素类型英文名称' }]"
                >
                <a-input v-model:value="formState.elementTypeEnName"/>
              </a-form-item>
            </a-col>
          </a-row>   
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="elementTypeCnName" 
                label="要素类型中文名称"
                :rules="[{ required: true, message: '请输入要素类型中文名称' }]"
                >
                <a-input v-model:value="formState.elementTypeCnName"/>
              </a-form-item>
            </a-col>
          </a-row>                  
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item
                name="channelId"
                label="渠道平台"
                :rules="[{ required: true, message: '请选择渠道平台' }]"
              >
                <a-select
                  v-model:value="formState.channelId"
                  placeholder="请选择渠道平台"
                  :loading="transChannelLoading"
                  allowClear 
                  @change="handleTransChannelSelectChange " 
                >              
                  <!-- 遍历渠道平台列表生成选项 -->
                  <a-select-option 
                    v-for="transChannel in transChannelList" 
                    :key="transChannel.transChannelCode" 
                    :value="transChannel.transChannelCode"
                  >
                    {{ transChannel.transChannelName }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="elementType" 
                label="要素类型"
                :rules="[{ required: true, message: '请输入要素类型' }]"
                >
                <a-select
                  v-model:value="formState.elementType"
                  placeholder="请选择要素类型"
                  :loading="elementTypeLoading"
                  allowClear        
                >
                  <!-- 遍历字典列表生成选项 -->
                  <a-select-option 
                    v-for="dictDate in elementTypeList" 
                    :key="dictDate.dictType" 
                    :value="dictDate.dictValue"
                  >
                    {{ dictDate.dictLabel }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row> 
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="chooseGroupId" 
                label="关联选择组"
                :rules="[{ required: true, message: '请输入关联选择组' }]"
                >
                  <a-select
                    v-model:value="formState.chooseGroupId"
                    placeholder="请选择关联选择组"
                    :loading="chooseGroupLoading"
                    allowClear 
                    @change="handleChooseGroupSelectChange "  
                  >              
                  <!-- 遍历选择组列表生成选项 -->
                  <a-select-option 
                    v-for="chooseGroup in chooseGroupList" 
                    :key="chooseGroup.chooseGroupId" 
                    :value="chooseGroup.chooseGroupId"
                  >
                    {{ chooseGroup.chooseGroupName }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>                      
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="checkScriptFlag" 
                label="是否验证正则或者脚本"
                :rules="[{ required: true, message: '请输入是否验证正则或者脚本' }]"
                >
                <a-select
                  v-model:value="formState.checkScriptFlag"
                  placeholder="请选择是否验证正则或者脚本"
                  :loading="checkScriptFlagLoading"
                  allowClear        
                >
                  <!-- 遍历字典列表生成选项 -->
                  <a-select-option 
                    v-for="dictDate in checkScriptFlagList" 
                    :key="dictDate.dictType" 
                    :value="dictDate.dictValue"
                  >
                    {{ dictDate.dictLabel }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>  
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="checkScriptContext" 
                label="正则或脚本内容"
                >
                <a-input v-model:value="formState.checkScriptContext"/>
              </a-form-item>
            </a-col>
          </a-row>  
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="responseType" 
                label="返回类型"
                :rules="[{ required: true, message: '返回类型' }]"
                >
                <a-select
                  v-model:value="formState.responseType"
                  placeholder="请选择返回类型"
                  :loading="responseTypeLoading"
                  allowClear        
                >
                  <!-- 遍历字典列表生成选项 -->
                  <a-select-option 
                    v-for="dictDate in responseTypeList" 
                    :key="dictDate.dictType" 
                    :value="dictDate.dictValue"
                  >
                    {{ dictDate.dictLabel }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item 
                name="enteringLabelType" 
                label="录入标签类型"
                :rules="[{ required: true, message: '请输入录入标签类型' }]"
                >
                <a-select
                  v-model:value="formState.enteringLabelType"
                  placeholder="请选择录入标签类型"
                  :loading="enteringLabelTypeLoading"
                  allowClear        
                >
                  <!-- 遍历字典列表生成选项 -->
                  <a-select-option 
                    v-for="dictDate in enteringLabelTypeList" 
                    :key="dictDate.dictType" 
                    :value="dictDate.dictValue"
                  >
                    {{ dictDate.dictLabel }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>    
          <a-row :gutter="24">
            <a-col :span="14" :offset="6">
              <a-form-item name="remarks"  label="备注" >
                <a-input v-model:value="formState.remarks"/>
              </a-form-item>
            </a-col>
          </a-row>                                                                                         
        </a-form>
      </a-modal>
    </a-space>
  </template>
  <script lang="ts" setup>
  // base library
  import { LISTHEADER } from "./config"; // 从同级config.ts文件中导入表头
  import { listQuery, add, edit, del} from "@/api/pmManagement/PmElementType/PmElementType";
  import { fetchDictData, DictItem, convertDictValue, TransChannelItem, fetchTransChannelList, handleTransChannelChange, GroupItem, fetchGroupList, filterGroup, handleModalGroupChange } from "@/utils/utils"; // 导入公共方法和接口
  import { onMounted } from "@vue/runtime-core";
  import {
    computed,
    createVNode,
    reactive,
    ref,
    toRaw,
    unref,
  } from "vue";
  import { FormInstance, message, Modal } from "ant-design-vue";
  import { ExclamationCircleOutlined, DeleteOutlined } from "@ant-design/icons-vue";
  
  const searchRef = ref<FormInstance>();
  let searchLoading = ref(true);
  const searchFormState: { [propName: string]: any } = reactive({});
  
  const columns = LISTHEADER;
  let pageNum = ref(1);
  let pageSize = ref(10);
  let total = ref(0);
  let data = ref([]);

  // 渠道平台列表
  const transChannelList = ref<TransChannelItem[]>([]);
  const transChannelLoading = ref(false);

  // ① 要素类型字典
  const elementTypeList = ref<DictItem[]>([]);
  const elementTypeLoading = ref(false);
  // 
  const checkScriptFlagList = ref<DictItem[]>([]);
  const checkScriptFlagLoading = ref(false);
  // 
  const responseTypeList = ref<DictItem[]>([]);
  const responseTypeLoading = ref(false);
  // 
  const enteringLabelTypeList = ref<DictItem[]>([]);
  const enteringLabelTypeLoading = ref(false);

  // 选择组列表
  const chooseGroupList = ref<GroupItem[]>([]);
  const chooseGroupLoading = ref(false); 

  const handleSearch = (values?: any) => {
    searchLoading.value = true;
    console.log("Received values of form: ", values);
    console.log("searchFormState: ", searchFormState);
    let parameter = { ...searchFormState };
    if (values?.current) {
      // 分页切换
      pageNum.value = values?.current;
      pageSize.value = values?.pageSize;
    } else {
      // 搜索
      selectedRowKeys.value = [];
      selectedRows.value = [];
      pageNum.value = 1;
    }
    const requestParameters = Object.assign({}, parameter, {
      pageNum: pageNum.value,
      pageSize: pageSize.value,
    });
    console.log("loadData request parameters:", requestParameters);
  
    // 列表查询及条件查询
    listQuery(requestParameters).then(
      (res: {
        code: number | string;
        msg: string;
        total: number;
        rows: any;
      }) => {
        console.log("打印完整的返回信息：" + res);
        searchLoading.value = false;
        const { code, msg, total: count, rows } = res;
        console.log("接口编码：" + code);
        console.log("接口信息：" + JSON.stringify(rows, null, 2))
        if (code === 200) {
          data.value = rows;
          total.value = count;
        } else {
          total.value = 0;
          data.value = [];
          pageNum.value = 1;
          message.error(msg);
        }
      }
    );
  };
  type T = any
  // 查询出的数据表单展示后，选择数据，对选中的数据进行赋值
  const selectedRowKeys = ref<string[]>([]); // 一般存放选中数据的id，由rowKey控制，rowKey取啥字段就存啥字段的值
  const selectedRows = ref<T[]>([]); // 存放选中行的所有数据
  const onSelectChange = (changableRowKeys: string[], changableRows: T[]) => {
    console.log("选中的行ID:", selectedRowKeys);
    console.log("选中的行数据:", selectedRows);
    console.log("selectedRowKeys changed: ", changableRowKeys);
    selectedRowKeys.value = changableRowKeys;
    selectedRows.value = changableRows;
  };
  const rowSelection = computed(() => {
    return {
      selectedRowKeys: unref(selectedRowKeys),
      onChange: onSelectChange,
      hideDefaultSelections: false,
    };
  });
  enum action {
    add = "新增",
    edit = "编辑",
  }
  const currentAction = ref(action.add);
  const visible = ref<boolean>(false);
  const modalTitleRef = ref<HTMLElement>();

  // 表单字段定义，一般是弹窗中的表单
  interface FormValues {
    id: string;
    elementTypeEnName: string;
    elementTypeCnName: string;
    channelId: string;
    channelName: string;
    elementType: string;
    chooseGroupId: string;
    chooseGroupName: string;
    checkScriptFlag: string;
    checkScriptContext: string;
    responseType: string;
    enteringLabelType: string;
    remarks: string;
  }
  const formRef = ref<FormInstance>();
  const formState = reactive<FormValues>({ // 表单数据初始化
    id: "",
    elementTypeEnName: "",
    elementTypeCnName: "",
    channelId: "",
    channelName: "",
    elementType: "",
    chooseGroupId: "",
    chooseGroupName: "",
    checkScriptFlag: "",
    checkScriptContext: "",
    responseType: "",
    enteringLabelType: "",
    remarks: ""
  });
  // 备份初始化为空的表单数据，用于新增按钮时置空可能存在的遗留表单数据
  const formBackup = { ...formState };
  const reset = () => {
    formRef.value?.resetFields(); 
    Object.assign(formState, formBackup);
  }

  // 弹窗中渠道平台选择器的change事件直接调用工具方法
  const handleTransChannelSelectChange = (code: string) => {
    handleTransChannelChange(code, transChannelList.value, formState);
  };  

  // 弹窗中币种选择器的change事件直接调用工具方法
  const handleChooseGroupSelectChange = (code: string) => {
    handleModalGroupChange(code, chooseGroupList.value, formState);
  }; 

  // 新增弹窗页面，并对表单数据进行初始化为空，防止出现先打开编辑弹窗后，遗留表单数据
  const showModal = () => {
    reset();
    formState.id = "";//resetFields() 对 id 字段无效！因为弹窗表单中没有 id 对应的表单控件,手动重置id，双重保障         
    visible.value = true;
    currentAction.value = action.add;
  };
  // 编辑弹窗页面
  const showEditModal = () => {
    if (selectedRowKeys.value.length > 1)
      message.error("仅能选择一条记录进行操作");
    if (selectedRowKeys.value.length === 0)
      message.error("请选择一条记录进行操作");
    if (selectedRowKeys.value.length === 1) {
      currentAction.value = action.edit;
      visible.value = true;
      formRef.value?.resetFields();
      // 渲染【编辑】弹窗中的数据
      // 1. 获取选中行数据
      const rowData = selectedRows.value[0];
      
      // 2. 批量转换枚举字段（根据字典类型和字典列表）
      const convertedData = {
        ...rowData,
        // 转换：要素类型（字典类型 'element_type'）
        elementType: convertDictValue(
          'element_type',
          rowData.elementType,
          elementTypeList.value
        ),
        // 转换：要素类型（字典类型 'check_script_flag'）
        checkScriptFlag: convertDictValue(
          'check_script_flag',
          rowData.checkScriptFlag,
          checkScriptFlagList.value
        ),
        // 转换：要素类型（字典类型 'response_ype'）
        responseType: convertDictValue(
          'response_ype',
          rowData.responseType,
          responseTypeList.value
        ),
        // 转换：要素类型（字典类型 'entering_label_type'）
        enteringLabelType: convertDictValue(
          'entering_label_type',
          rowData.enteringLabelType,
          enteringLabelTypeList.value
        ),                        
      };      
      Object.assign(formState, convertedData);

      // 调用工具方法同步名称
      handleTransChannelChange(formState.channelId, transChannelList.value, formState);
    }
  };
  // 弹窗页面中确定按钮点击事件，由于新增和修改共用一个弹窗页面，故可以在此方法中判断新增和更新方法
  const handleOk = (e: MouseEvent) => {
    console.log(e);
    // visible.value = false;
    formRef.value
      .validateFields()
      .then((values) => {
        console.log("Received values of form: ", values);
        console.log("formState: ", toRaw(formState));
        visible.value = false;
        // 当前action为add时，调用新增方法add
        if (currentAction.value === action.add) {
          add(formState).then((res: { code: number; msg: string; }) => {
            const { code, msg } = res;
            if (code === 200) {
              Modal.success({
                title: msg,
              });
              formRef.value?.resetFields();
              console.log("reset formState: ", toRaw(formState));
            } else {
              Modal.error({
                title: msg,
              });
            }
            handleSearch();
          });
        }
        // 当前action为edit时，调用编辑方法edit
        if (currentAction.value === action.edit) {
          edit(formState).then((res: { code: number; msg: string; }) => {
            const { code, msg } = res;
            if (code === 200) {
              Modal.success({
                title: msg,
              });
              formRef.value?.resetFields();
              console.log("reset formState: ", toRaw(formState));
            } else {
              Modal.error({
                title: msg,
              });
            }
            handleSearch();
          });
        }
      })
      .catch((info) => {
        console.log("Validate Failed:", info);
      });
  };
  // 删除弹窗页面，选中数据后，点击删除，调用del删除方法
  const showDelete = () => {
    if (selectedRowKeys.value.length === 0){
      message.error("请选择一条记录进行操作");
    } else {
      Modal.confirm({
        title: "请确认是否操作删除?",
        icon: createVNode(ExclamationCircleOutlined),
        okText: "删除",
        okType: "danger",
        cancelText: "取消",
        onOk() {
          console.log("selectedRows: ", toRaw(selectedRows.value[0]).id,selectedRows);
          del(selectedRowKeys.value).then((res: { code: number; msg: string; }) => {
            const { code, msg } = res;
            if (code === 200) {
              console.log("resp: ", toRaw(res));
              Modal.success({
                title: msg,
              });
              handleSearch();
            } else {
              Modal.error({
                title: msg,
              });
            }
          });
        },
        onCancel() {
          console.log("Cancel");
        },
      });
    }
  };
  onMounted(() => {
    searchLoading.value = false;
    fetchTransChannelList(transChannelList, transChannelLoading);
    fetchGroupList(chooseGroupList, chooseGroupLoading);
    fetchDictData("element_type", elementTypeList, elementTypeLoading);
    fetchDictData("check_script_flag", checkScriptFlagList, checkScriptFlagLoading);
    fetchDictData("response_type", responseTypeList, responseTypeLoading);
    fetchDictData("entering_label_type", enteringLabelTypeList, enteringLabelTypeLoading);
    //   handleSearch();
  });
  </script>
  <script lang="ts">
  import {
    AppstoreAddOutlined,
    FormOutlined,
  } from "@ant-design/icons-vue";
  
  export default {
    name: "userConfig",
    components: {
      AppstoreAddOutlined,
      FormOutlined,
    },
  };
  </script>
  
  <style type="less" scoped>
  /* .ant-form-item-label > label {
    width:150px!important;
    justify-content: end!important;
  } */
  .ant-table-striped :deep(.table-striped) td {
    background-color: #fafafa;
  }
  
  </style>
  